package com.iplant.aps.serviceimpl;

import com.iplant.aps.service.BPMService;
import com.iplant.aps.service.mesenum.BFCMessageType;
import com.iplant.aps.service.mesenum.BPMEventModule;
import com.iplant.aps.service.mesenum.BPMHistoryTaskStatus;
import com.iplant.aps.service.mesenum.MESException;
import com.iplant.aps.service.po.APIResult;
import com.iplant.aps.service.po.OutResult;
import com.iplant.aps.service.po.ServiceResult;
import com.iplant.aps.service.po.bfc.BFCMessage;
import com.iplant.aps.service.po.bms.BMSEmployee;
import com.iplant.aps.service.po.bpm.*;
import com.iplant.aps.service.po.excel.MyExcelSheet;
import com.iplant.aps.service.utils.CloneTool;
import com.iplant.aps.service.utils.Configuration;
import com.iplant.aps.service.utils.StringUtils;
import com.iplant.aps.serviceimpl.dao.BaseDAO;
import com.iplant.aps.serviceimpl.utils.aps.APSConstans;
import com.iplant.aps.utils.RemoteInvokeUtils;
import com.iplant.aps.utils.RetCode;
import com.iplant.aps.utils.aps.ExcelUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author Femi
 *         2019年12月27日12:46:35
 */
@Service
public class BPMServiceImpl implements BPMService {

    private static final Logger logger = LoggerFactory.getLogger(BPMServiceImpl.class);

    public BPMServiceImpl() {
    }

    private static BPMService Instance;

    public static BPMService getInstance() {
        if (Instance == null)
            Instance = new BPMServiceImpl();
        return Instance;
    }

    @Override
    public APIResult BPM_CreateProcess(BMSEmployee wLoginUser, BPMEventModule wModule, int wSheetID, Object wData) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("processDefinitionKey", "_" + wModule.getValue());
            wParms.put("BusinessKey", wSheetID + "");

            if (wData == null) {
                wData = new HashMap<String, Object>();
            }
            Map<String, Object> wMap = CloneTool.Clone(wData, Map.class);
            for (String wKey : wMap.keySet()) {
                wMap.putIfAbsent(wKey, "");
                if (wMap.get(wKey).getClass().isArray()) {
                    wMap.put(wKey, StringUtils.Join(",", (Object[]) wMap.get(wKey)));
                }
                if (wMap.get(wKey) instanceof Collection<?>) {
                    wMap.put(wKey, StringUtils.Join(",", (Collection<?>) wMap.get(wKey)));
                }
            }

            wParms.put("data", wMap);
            if (wMap.containsKey("Code")) {
                wParms.put("processInstanceCode", wMap.get("Code"));
                if (!wMap.containsKey("processInstanceCode"))
                    wMap.put("processInstanceCode", wMap.get("Code"));
            }

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/startProcessByProcessDefinitionKey?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.POST);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_CompleteTask(BMSEmployee wLoginUser, int wTaskID, int wLocalScope, Object wData) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("TaskID", wTaskID + "");
            wParms.put("localScope", wLocalScope);

            if (wData == null) {
                wData = new HashMap<String, Object>();
            }

            Map<String, Object> wMap = CloneTool.Clone(wData, Map.class);
            for (String wKey : wMap.keySet()) {
                wMap.putIfAbsent(wKey, "");
                if (wMap.get(wKey).getClass().isArray()) {
                    wMap.put(wKey, StringUtils.Join(",", (Object[]) wMap.get(wKey)));
                }
                if (wMap.get(wKey) instanceof Collection<?>) {
                    wMap.put(wKey, StringUtils.Join(",", (Collection<?>) wMap.get(wKey)));
                }
                if (wMap.get(wKey) instanceof Integer) {
                    wMap.put(wKey, StringUtils.parseString(wMap.get(wKey)));
                }
            }

            wParms.put("data", wMap);
            if (wMap.containsKey("Code"))
                wParms.put("processInstanceCode", wMap.get("Code"));

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/CompleteMyPersonalTask?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.POST);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetTask(BMSEmployee wLoginUser, int wTaskID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("taskId", wTaskID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/History/getBPMActivitiHisTaskByTaskId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_CurrentTask(BMSEmployee wLoginUser, int wProcessInstanceID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("processInstanceId", wProcessInstanceID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Leave/CurrentTask?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetOperationByTaskID(BMSEmployee wLoginUser, int wTaskID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("taskId", wTaskID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Repository/getNextSFConditionByTaskId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetTaskListByInstance(BMSEmployee wLoginUser, int wInstanceID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("processInstanceId", wInstanceID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/getUnfinishedTaskByPIId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Boolean> BPM_MsgUpdate(BMSEmployee wLoginUser, int wTaskID, int wLocalScope,
            BPMTaskBase wBPMTaskBase, Object wData) {
        ServiceResult<Boolean> wResult = new ServiceResult<>(false);
        try {
            APIResult wAPIResult = BPM_CompleteTask(wLoginUser, wTaskID, wLocalScope, wData);

            if (wAPIResult.getResultCode() != RetCode.SERVER_CODE_SUC) {
                wResult.FaultCode += wAPIResult.getMsg();
            }

            BPMActivitiHisTask wHisTask = BPM_GetTask(wLoginUser, wTaskID).Info(BPMActivitiHisTask.class);
            if (wHisTask == null || StringUtils.isEmpty(wHisTask.ID)) {
                wResult.FaultCode += "任务不存在！";
                return wResult;
            }
            if (wHisTask.Status != BPMHistoryTaskStatus.NomalFinished.getValue()) {
                return wResult;
            }

            BPMActivitiTask wSelfTask = BPM_GetTask(wLoginUser, wTaskID).Info(BPMActivitiTask.class);
            if ((wSelfTask == null) || (StringUtils.isEmpty(wSelfTask.ID))
                    || (wTaskID != StringUtils.parseInt(wSelfTask.ID))) {
                wResult.Result = Boolean.TRUE;
                wResult.FaultCode += "任务不存在！";
                return wResult;
            }

            List<BPMActivitiTask> wBPMActivitiTaskList = wAPIResult.List(BPMActivitiTask.class);
            List<Integer> wNotifyUserIDList = new ArrayList<>();
            if (wAPIResult.getReturnObject().containsKey("NotifyList")) {
                wNotifyUserIDList = StringUtils
                        .parseIntList(wAPIResult.getReturnObject().get("NotifyList").toString().split(","));
            }

            List<BFCMessage> wBFCMessageList = new ArrayList<>();
            BFCMessage wBFCMessage = null;
            BFCMessage wBFCMessageClone = null;

            List<String> wStatusList = StringUtils.parseList(StringUtils.split(wBPMTaskBase.StatusText, ","));
            if (wStatusList.contains("待" + wSelfTask.Name) && wBPMActivitiTaskList.size() > 0)
                wStatusList.remove("待" + wSelfTask.Name);

            if (wBPMActivitiTaskList.size() > 0) {
                wStatusList.removeIf(p -> wBPMActivitiTaskList.stream().noneMatch(q -> p.equals("待" + q.Name)));
            }

            if (wBPMTaskBase.FollowerID.contains(wLoginUser.getID())) {
                wBPMTaskBase.FollowerID.remove(Integer.valueOf(wLoginUser.getID()));
            }
            List<Integer> wUserIDList = null;
            for (BPMActivitiTask bpmActivitiTask : wBPMActivitiTaskList) {
                if (bpmActivitiTask == null) {
                    continue;
                }

                wBFCMessage = new BFCMessage();
                wBFCMessage.Active = 0;
                wBFCMessage.CompanyID = wLoginUser.getCompanyID();
                wBFCMessage.MessageID = wBPMTaskBase.getID();
                wBFCMessage.ModuleID = wBPMTaskBase.getFlowType();
                wBFCMessage.Type = BFCMessageType.Task.getValue();
                wBFCMessage.ShiftID = 0;
                wBFCMessage.StepID = StringUtils.parseInt(bpmActivitiTask.ID);
                wBFCMessage.Title = StringUtils.Format("{0}", wBPMTaskBase.Code);
                wBFCMessage.MessageText = StringUtils.Format("模块：{0} 发起人：{1}  发起时刻：{2} 待{3}",
                        BPMEventModule.getEnumType(wBPMTaskBase.getFlowType()).getLable(),
                        wBPMTaskBase.UpFlowName,
                        StringUtils.parseCalendarToString(wBPMTaskBase.CreateTime, "yyyy-MM-dd HH:mm"),
                        bpmActivitiTask.Name)
                        .trim();
                wBFCMessage.CreateTime = Calendar.getInstance();

                if (StringUtils.isEmpty(bpmActivitiTask.Assignee))
                    bpmActivitiTask.Assignee = "";
                if (StringUtils.isEmpty(bpmActivitiTask.Recipients))
                    bpmActivitiTask.Recipients = "";
                wUserIDList = StringUtils.parseIntList(bpmActivitiTask.Assignee.split(","));
                List<Integer> wRecipientList = StringUtils.parseIntList(bpmActivitiTask.Recipients.split(","));
                wRecipientList.removeAll(wUserIDList);

                for (Integer wResponsorID : wUserIDList) {
                    if (wResponsorID <= 0) {
                        if (wResponsorID != BaseDAO.SysAdmin.getID())
                            continue;
                        wBPMTaskBase.setStepID(StringUtils.parseInt(bpmActivitiTask.ID));

                        APSConstans.SetBizTask(wBPMTaskBase);
                    } else {
                        wBFCMessageClone = CloneTool.Clone(wBFCMessage, BFCMessage.class);
                        wBFCMessageClone.ResponsorID = wResponsorID;
                        wBFCMessageList.add(wBFCMessageClone);
                        // WDWConstans.SetBizTask(wBPMTaskBase);
                    }
                }
                for (Integer wResponsorID : wRecipientList) {
                    if (wResponsorID <= 0) {
                        continue;
                    }
                    wBFCMessage.Type = BFCMessageType.Notify.getValue();
                    wBFCMessageClone = CloneTool.Clone(wBFCMessage, BFCMessage.class);
                    wBFCMessageClone.ResponsorID = wResponsorID;
                    wBFCMessageList.add(wBFCMessageClone);
                }

                wNotifyUserIDList.removeAll(wUserIDList);
                wNotifyUserIDList.removeAll(wRecipientList);

                wBPMTaskBase.FollowerID.addAll(wUserIDList);
                if (wUserIDList.size() == 0 && wUserIDList.contains(BaseDAO.SysAdmin.getID()))
                    continue;
                if (!wStatusList.contains("待" + bpmActivitiTask.Name)) {
                    wStatusList.add("待" + bpmActivitiTask.Name);
                }
            }
            wBPMTaskBase.StatusText = StringUtils.Join(",", wStatusList);
            if (StringUtils.isEmpty(wBPMTaskBase.StatusText)) {
                wBPMTaskBase.StatusText = "已" + wSelfTask.Name;
            }
            if (wNotifyUserIDList.size() > 0) {
                for (Integer wResponsorID : wNotifyUserIDList) {
                    wBFCMessage = new BFCMessage();
                    wBFCMessage.Active = 0;
                    wBFCMessage.CompanyID = wLoginUser.getCompanyID();
                    wBFCMessage.MessageID = wBPMTaskBase.getID();
                    wBFCMessage.ModuleID = wBPMTaskBase.getFlowType();
                    wBFCMessage.Type = BFCMessageType.Notify.getValue();
                    wBFCMessage.ShiftID = 0;
                    wBFCMessage.StepID = StringUtils.parseInt(wSelfTask.ID);
                    wBFCMessage.Title = StringUtils.Format("{0}", wBPMTaskBase.Code);
                    wBFCMessage.MessageText = StringUtils.Format("模块：{0} 发起人：{1} 发起时刻：{2}  已{3}",
                            BPMEventModule.getEnumType(wBPMTaskBase.getFlowType()).getLable(),
                            wBPMTaskBase.UpFlowName,
                            StringUtils.parseCalendarToString(wBPMTaskBase.CreateTime, "yyyy-MM-dd HH:mm"),
                            wSelfTask.Name);
                    wBFCMessage.ResponsorID = wResponsorID;
                    wBFCMessage.CreateTime = Calendar.getInstance();
                    wBFCMessageList.add(wBFCMessage);
                }

            }

            CoreServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);

            // 判断任务是否结束

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error("BPMService--BPM_MsgUpdate", e);
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetInstanceByID(BMSEmployee wLoginUser, int wFlowID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("processInstanceId", wFlowID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/History/getBPMActivitiProcessInstanceByPIId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetHistoryInstanceByID(BMSEmployee wLoginUser, int processInstanceId) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("processInstanceId", processInstanceId);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/History/getBPMActivitiHisTaskByPIId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_DeleteInstanceByID(BMSEmployee wLoginUser, int wFlowID, String wReason) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("processInstanceId", wFlowID + "");
            wParms.put("deleteReason", wReason);
            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/deleteProcessInstance?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetActivitiHisTaskByPIId(BMSEmployee wLoginUser, int wFlowID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("processInstanceId", wFlowID + "");
            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/History/getBPMActivitiHisTaskByPIId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_DelegateTask(BMSEmployee wLoginUser, String taskId, String userId, String remark) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("taskId", taskId);
            wParms.put("userId", userId);
            wParms.put("remark", remark);
            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/delegateTask?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.POST);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> BPM_ExportData(BMSEmployee wLoginUser, List<BPMPropDesc> wMainProp, List<Map> wDataMap,
            String wTitle) {
        ServiceResult<String> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            MyExcelSheet wMyExcelSheet = BPM_GetExportExcelSheet(wLoginUser, wMainProp, wDataMap, wTitle, wErrorCode);

            List<MyExcelSheet> wMyExcelSheetList = new ArrayList<MyExcelSheet>(
                    Collections.singletonList(wMyExcelSheet));

            wResult.Result = ExcelUtil.ExportData(wMyExcelSheetList, wTitle);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取导出数据
     */
    // private MyExcelSheet BPM_GetExportExcelSheet(BMSEmployee wLoginUser, List<BPMPropDesc> wMainProp,
    //         List<Map> wDataMap,
    //         String wTitle, OutResult<Integer> wErrorCode) {
    //     MyExcelSheet wResult = new MyExcelSheet();
    //     try {
    //         wResult.SheetName = wTitle;
    //         wResult.TitleName = "";
    //         wResult.HeaderList = new ArrayList<>();
    //         wResult.DataList = new ArrayList<>();

    //         Map<String, String> wTaskTitileValueMap = new HashMap<>();
    //         String wServerUrl = Configuration.readConfigString("core.server.url", "config/config");
    //         String wTempServerUrl = wServerUrl.substring(0, wServerUrl.length() - 1);
    //         // ①遍历获取所有流程数据
    //         Map<Integer, List<BPMActivitiHisTask>> wTaskActivitiTaskListMap = new HashMap<>();
    //         for (Map wMap : wDataMap) {
    //             if (!((Map<String, Object>) wMap).containsKey("FlowID")) {
    //                 continue;
    //             }
    //             if (!((Map<String, Object>) wMap).containsKey("ID")) {
    //                 continue;
    //             }

    //             int wFlowID = StringUtils.parseInt(((Map<String, Object>) wMap).get("FlowID"));
    //             if (wFlowID <= 0) {
    //                 continue;
    //             }

    //             int wID = StringUtils.parseInt(((Map<String, Object>) wMap).get("ID"));
    //             if (wID <= 0) {
    //                 continue;
    //             }

    //             List<BPMActivitiHisTask> wHisList = BPMServiceImpl.getInstance()
    //                     .BPM_GetHistoryInstanceByID(wLoginUser, wFlowID).List(BPMActivitiHisTask.class);
    //             if (wHisList == null || wHisList.size() <= 0) {
    //                 continue;
    //             }

    //             wTaskActivitiTaskListMap.put(wID, wHisList);

    //             // 收集数据集
    //             for (BPMPropDesc bpmPropDesc : wMainProp) {
    //                 if (!((Map<String, Object>) wMap).containsKey(bpmPropDesc.keyName)) {
    //                     continue;
    //                 }

    //                 Object wDataObj = ((Map<String, Object>) wMap).get(bpmPropDesc.keyName);
    //                 String wTaskValueKey = StringUtils.Format("{0}::{1}", wID,
    //                         bpmPropDesc.showName);
    //                 String wTaskValueValue = StringUtils.parseString(wDataObj);
    //                 if (wTaskValueValue.contains("/MESCore/upload")) {
    //                     wTaskValueValue = getImageValues(wTempServerUrl, wTaskValueValue);
    //                 }
    //                 wTaskTitileValueMap.put(wTaskValueKey, wTaskValueValue);
    //             }
    //         }
    //         // ②获取标题/数据集
    //         if (wMainProp != null && wMainProp.size() > 0) {
    //             for (BPMPropDesc bpmPropDesc : wMainProp) {
    //                 wResult.HeaderList.add(bpmPropDesc.showName);
    //             }

    //             // 动态标题
    //             for (int wTaskID : wTaskActivitiTaskListMap.keySet()) {
    //                 List<BPMActivitiHisTask> bpmActivitiHisTasks = wTaskActivitiTaskListMap.get(wTaskID);
    //                 for (BPMActivitiHisTask bpmActivitiHisTask : bpmActivitiHisTasks) {

    //                     // 添加节点人
    //                     String wFormTitle1 = StringUtils.Format("{0}_{1}", bpmActivitiHisTask.Name,
    //                             "执行人");
    //                     if (wResult.HeaderList.stream().noneMatch(p -> p.equals(wFormTitle1))) {
    //                         wResult.HeaderList.add(wFormTitle1);
    //                     }
    //                     String wTaskValueKey1 = StringUtils.Format("{0}::{1}", wTaskID, wFormTitle1);
    //                     String wTaskValueValue1 = "";
    //                     String wTaskValueValue2 = "";
    //                     if (bpmActivitiHisTask.Status == 0) {
    //                         wTaskValueValue1 = "";
    //                         wTaskValueValue2 = "";
    //                     } else {
    //                         wTaskValueValue1 = getUserNameByAssine(bpmActivitiHisTask.Assignee);
    //                         wTaskValueValue2 = StringUtils.parseCalendarToString(bpmActivitiHisTask.EndTime, "yyyy" +
    //                                 "-MM-dd HH:mm:ss");
    //                     }
    //                     wTaskTitileValueMap.put(wTaskValueKey1, wTaskValueValue1);
    //                     // 节点时间
    //                     String wFormTitle2 = StringUtils.Format("{0}_{1}", bpmActivitiHisTask.Name,
    //                             "执行时间");
    //                     if (wResult.HeaderList.stream().noneMatch(p -> p.equals(wFormTitle2))) {
    //                         wResult.HeaderList.add(wFormTitle2);
    //                     }
    //                     String wTaskValueKey2 = StringUtils.Format("{0}::{1}", wTaskID, wFormTitle2);
    //                     wTaskTitileValueMap.put(wTaskValueKey2, wTaskValueValue2);

    //                     for (BPMActivitiHisTaskVarinst bpmActivitiHisTaskVarinst : bpmActivitiHisTask.HisTaskVarinstList) {
    //                         if (wDataMap.get(0).containsKey(bpmActivitiHisTaskVarinst.VariableName)
    //                                 && !bpmActivitiHisTaskVarinst.VariableName.contains("Remark")
    //                                 && !bpmActivitiHisTaskVarinst.VariableName.contains("ImageList")) {
    //                             continue;
    //                         }

    //                         if (bpmActivitiHisTaskVarinst.formProperty == null
    //                                 || StringUtils.isEmpty(bpmActivitiHisTaskVarinst.formProperty.name)) {
    //                             continue;
    //                         }

    //                         if (wMainProp.stream()
    //                                 .anyMatch(p -> p.showName.equals(bpmActivitiHisTaskVarinst.formProperty.name))) {
    //                             continue;
    //                         }

    //                         if (!bpmActivitiHisTaskVarinst._BPMActivitiForm.IsReadable) {
    //                             continue;
    //                         }

    //                         String wFormTitle = StringUtils.Format("{0}_{1}", bpmActivitiHisTask.Name,
    //                                 bpmActivitiHisTaskVarinst.formProperty.name);
    //                         if (wResult.HeaderList.stream().noneMatch(p -> p.equals(wFormTitle))) {
    //                             wResult.HeaderList.add(wFormTitle);
    //                         }

    //                         // 保存数据值
    //                         String wTaskValueKey = StringUtils.Format("{0}::{1}", wTaskID, wFormTitle);
    //                         String wTaskValueValue = bpmActivitiHisTaskVarinst.ValueText;
    //                         if (wTaskValueValue.contains("/MESCore/upload")) {
    //                             wTaskValueValue = getImageValues(wTempServerUrl, wTaskValueValue);
    //                         }
    //                         wTaskTitileValueMap.put(wTaskValueKey, wTaskValueValue);
    //                     }
    //                 }
    //             }
    //         }
    //         // ③获取行数据
    //         for (Map wMap : wDataMap) {
    //             if (!((Map<String, Object>) wMap).containsKey("ID")) {
    //                 continue;
    //             }

    //             int wID = StringUtils.parseInt(((Map<String, Object>) wMap).get("ID"));
    //             if (wID <= 0) {
    //                 continue;
    //             }

    //             List<String> wValueList = new ArrayList<>();
    //             for (String wExcelTitle : wResult.HeaderList) {
    //                 String wKey = StringUtils.Format("{0}::{1}", wID, wExcelTitle);
    //                 wValueList.add(wTaskTitileValueMap.getOrDefault(wKey, ""));
    //             }
    //             wResult.DataList.add(wValueList);
    //         }
    //     } catch (Exception ex) {
    //         logger.error("BPM_GetExportExcelSheet", ex);
    //     }
    //     return wResult;
    // }

    /**
     * 获取导出数据
     */
    private MyExcelSheet BPM_GetExportExcelSheet(BMSEmployee wLoginUser, List<BPMPropDesc> wMainProp,
            List<Map> wDataMap,
            String wTitle, OutResult<Integer> wErrorCode) {
        MyExcelSheet wResult = new MyExcelSheet();
        try {
            wResult.SheetName = wTitle;
            wResult.TitleName = "";
            wResult.HeaderList = new ArrayList<>();
            wResult.DataList = new ArrayList<>();

            Map<String, String> wTaskTitileValueMap = new HashMap<>();
            String wServerUrl = Configuration.readConfigString("core.server.url", "config/config");
            String wTempServerUrl = wServerUrl.substring(0, wServerUrl.length() - 1);

            // ①遍历获取所有流程数据
            Map<Integer, List<BPMActivitiHisTask>> wTaskActivitiTaskListMap = new HashMap<>();
            for (Map wMap : wDataMap) {
                if (!((Map<String, Object>) wMap).containsKey("FlowID")) {
                    continue;
                }
                if (!((Map<String, Object>) wMap).containsKey("ID")) {
                    continue;
                }

                int wFlowID = StringUtils.parseInt(((Map<String, Object>) wMap).get("FlowID"));
                if (wFlowID <= 0) {
                    continue;
                }

                int wID = StringUtils.parseInt(((Map<String, Object>) wMap).get("ID"));
                if (wID <= 0) {
                    continue;
                }

                List<BPMActivitiHisTask> wHisList = BPMServiceImpl.getInstance()
                        .BPM_GetHistoryInstanceByID(wLoginUser, wFlowID).List(BPMActivitiHisTask.class);
                if (wHisList == null || wHisList.size() <= 0) {
                    continue;
                }

                wTaskActivitiTaskListMap.put(wID, wHisList);

                // 收集数据集
                for (BPMPropDesc bpmPropDesc : wMainProp) {
                    if (!((Map<String, Object>) wMap).containsKey(bpmPropDesc.keyName)) {
                        continue;
                    }

                    Object wDataObj = ((Map<String, Object>) wMap).get(bpmPropDesc.keyName);
                    String wTaskValueKey = StringUtils.Format("{0}::{1}", wID,
                            bpmPropDesc.showName);
                    String wTaskValueValue = StringUtils.parseString(wDataObj);
                    if (wTaskValueValue.contains("/MESCore/upload")) {
                        wTaskValueValue = getImageValues(wTempServerUrl, wTaskValueValue);
                    }
                    wTaskTitileValueMap.put(wTaskValueKey, wTaskValueValue);
                }
            }

            // ②获取标题/数据集
            if (wMainProp != null && wMainProp.size() > 0) {
                for (BPMPropDesc bpmPropDesc : wMainProp) {
                    wResult.HeaderList.add(bpmPropDesc.showName);
                }

                // 添加计数Map用于跟踪重复的Name
                Map<String, Integer> wNameCountMap = new HashMap<>();

                // 动态标题
                for (int wTaskID : wTaskActivitiTaskListMap.keySet()) {
                    List<BPMActivitiHisTask> bpmActivitiHisTasks = wTaskActivitiTaskListMap.get(wTaskID);
                    for (BPMActivitiHisTask bpmActivitiHisTask : bpmActivitiHisTasks) {
                        // 处理重复的Name
                        String wBaseName = bpmActivitiHisTask.Name;
                        String wActualName = wBaseName;
                        if (wNameCountMap.containsKey(wBaseName)) {
                            int wCount = wNameCountMap.get(wBaseName) + 1;
                            wNameCountMap.put(wBaseName, wCount);
                            wActualName = wBaseName + "_" + wCount;
                        } else {
                            wNameCountMap.put(wBaseName, 0);
                        }

                        // 添加节点人
                        String wFormTitle1 = StringUtils.Format("{0}_{1}", wActualName, "执行人");
                        if (wResult.HeaderList.stream().noneMatch(p -> p.equals(wFormTitle1))) {
                            wResult.HeaderList.add(wFormTitle1);
                        }
                        String wTaskValueKey1 = StringUtils.Format("{0}::{1}", wTaskID, wFormTitle1);
                        String wTaskValueValue1 = "";
                        String wTaskValueValue2 = "";
                        if (bpmActivitiHisTask.Status == 0) {
                            wTaskValueValue1 = "";
                            wTaskValueValue2 = "";
                        } else {
                            wTaskValueValue1 = getUserNameByAssine(bpmActivitiHisTask.Assignee);
                            wTaskValueValue2 = StringUtils.parseCalendarToString(bpmActivitiHisTask.EndTime,
                                    "yyyy-MM-dd HH:mm:ss");
                        }
                        wTaskTitileValueMap.put(wTaskValueKey1, wTaskValueValue1);

                        // 节点时间
                        String wFormTitle2 = StringUtils.Format("{0}_{1}", wActualName, "执行时间");
                        if (wResult.HeaderList.stream().noneMatch(p -> p.equals(wFormTitle2))) {
                            wResult.HeaderList.add(wFormTitle2);
                        }
                        String wTaskValueKey2 = StringUtils.Format("{0}::{1}", wTaskID, wFormTitle2);
                        wTaskTitileValueMap.put(wTaskValueKey2, wTaskValueValue2);

                        for (BPMActivitiHisTaskVarinst bpmActivitiHisTaskVarinst : bpmActivitiHisTask.HisTaskVarinstList) {
                            if (wDataMap.get(0).containsKey(bpmActivitiHisTaskVarinst.VariableName)
                                    && !bpmActivitiHisTaskVarinst.VariableName.contains("Remark")
                                    && !bpmActivitiHisTaskVarinst.VariableName.contains("ImageList")) {
                                continue;
                            }

                            if (bpmActivitiHisTaskVarinst.formProperty == null
                                    || StringUtils.isEmpty(bpmActivitiHisTaskVarinst.formProperty.name)) {
                                continue;
                            }

                            if (wMainProp.stream()
                                    .anyMatch(p -> p.showName.equals(bpmActivitiHisTaskVarinst.formProperty.name))) {
                                continue;
                            }

                            if (!bpmActivitiHisTaskVarinst._BPMActivitiForm.IsReadable) {
                                continue;
                            }

                            String wFormTitle = StringUtils.Format("{0}_{1}", wActualName,
                                    bpmActivitiHisTaskVarinst.formProperty.name);
                            if (wResult.HeaderList.stream().noneMatch(p -> p.equals(wFormTitle))) {
                                wResult.HeaderList.add(wFormTitle);
                            }

                            // 保存数据值
                            String wTaskValueKey = StringUtils.Format("{0}::{1}", wTaskID, wFormTitle);
                            String wTaskValueValue = bpmActivitiHisTaskVarinst.ValueText;
                            if (wTaskValueValue.contains("/MESCore/upload")) {
                                wTaskValueValue = getImageValues(wTempServerUrl, wTaskValueValue);
                            }
                            wTaskTitileValueMap.put(wTaskValueKey, wTaskValueValue);
                        }
                    }
                }
            }

            // ③获取行数据
            for (Map wMap : wDataMap) {
                if (!((Map<String, Object>) wMap).containsKey("ID")) {
                    continue;
                }

                int wID = StringUtils.parseInt(((Map<String, Object>) wMap).get("ID"));
                if (wID <= 0) {
                    continue;
                }

                List<String> wValueList = new ArrayList<>();
                for (String wExcelTitle : wResult.HeaderList) {
                    String wKey = StringUtils.Format("{0}::{1}", wID, wExcelTitle);
                    wValueList.add(wTaskTitileValueMap.getOrDefault(wKey, ""));
                }
                wResult.DataList.add(wValueList);
            }
        } catch (Exception ex) {
            logger.error("BPM_GetExportExcelSheet", ex);
        }
        return wResult;
    }

    private String getImageValues(String wUrl, String wTaskValueValue) {
        String wResult = "";
        try {
            if (StringUtils.isEmpty(wTaskValueValue)) {
                return wResult;
            }

            List<String> wList = new ArrayList<>();
            String[] split = wTaskValueValue.split(",");
            for (String s : split) {
                String tempStr = StringUtils.Format("{0}{1}", wUrl, s);
                wList.add(tempStr);
            }
            wResult = StringUtils.Join("\r\n", wList);
        } catch (Exception e) {
            logger.error("getImageValues", e);
        }
        return wResult;
    }

    private String getUserNameByAssine(String assignee) {
        String wResult = "";
        try {
            if (StringUtils.isEmpty(assignee)) {
                return wResult;
            }

            wResult = APSConstans.GetBMSEmployeeName(StringUtils.parseInt(assignee));
        } catch (Exception e) {
            logger.error("getUserNameByAssine", e);
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetFormByPdIdAndActId(BMSEmployee wLoginUser, String definitionId, String activitiId) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("definitionId", definitionId);
            wParms.put("activitiId", activitiId);
            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Repository/getFormByPdIdAndActId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }
}
